﻿
using EasyTest.Shared.EnumType;
using EasyTest.Shared.外部访问;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZLGCANoptimize.方法;

namespace ZLGCANoptimize
{

    public static class 数据
    {
        //public static string 远程IP = "192.168.10.130";   //FCT设备1 IP
        //public static int 类型 = 48;//400U是52,200U是48
        public static string 远程IP = "192.168.1.178";  //常用设备IP
        public static int 类型 = 52;  //400U是52,200U是48，100U是55,800U是57
        public static int 远程Port = 8000;
        public static int 本地Port = 9000;

        public static bool 初始化(int 通道, out ZLGCANHelper zLGCANHelper)
        {
            DeviceType deviceType = (DeviceType)类型;
            zLGCANHelper = new ZLGCANHelper(deviceType);
            zLGCANHelper.LocalPort = 本地Port;
            zLGCANHelper.RemotePort = 远程Port;
            zLGCANHelper.RemoteAddr = 远程IP;
            zLGCANHelper.Net_Mode = NetMode.客户端;

            //1、打开跟初始化
            uint device_index = 0;
            bool open = zLGCANHelper.Open(device_index);
            if (!open)
            {
                return false;
            }
            IntPtr intPtr = zLGCANHelper.Init(通道);
            open = zLGCANHelper.Start(intPtr);
            return open;
        }
        public static bool 设置参数(string IP地址 = "192.168.1.178", int CAN类型 = 52, int 远程端口 = 8989, int 本地端口 = 8000)
        {
            远程IP = IP地址;
            类型 = CAN类型;
            远程Port = 远程端口;
            本地Port = 本地端口;

            return true;
        }
        public static CanReadResponseModel 发送指令(CanReadRequestModel request)
        {
            CanReadResponseModel responseModel = new CanReadResponseModel();
            responseModel.ResultList = new List<string>();
            responseModel.ErrorMessage = string.Empty;
            try
            {
                //eLog.AddLog("1");
                //必要检查
                if (request.CmdList.Count() <= 0)
                {
                    return new CanReadResponseModel() { Success = false, ErrorMessage = "指令内容不能为空" };
                }
                if (!CheckCmdLength(request.CmdList))
                {
                    return new CanReadResponseModel() { Success = false, ErrorMessage = "指令内容长度有误" };
                }
                if (request.SendCmdTimeSpan <= 0)
                {
                    request.SendCmdTimeSpan = 30;  //未配置使用默认值
                }
                if (request.MaxSendCount <= 0)
                {
                    request.MaxSendCount = 1;  //未配置使用默认值
                }
                if (request.ReceiveCmdTimeSpan <= 0)
                {
                    request.ReceiveCmdTimeSpan = 1500;  //未配置使用默认值
                }
                if (request.IsDecode)
                {
                    if (string.IsNullOrWhiteSpace(request.DecodeLevel))
                    {
                        request.DecodeLevel = "62";
                    }

                    //如果输入的为16进制目标值，将目标值转换为十进制表示
                    if (!string.IsNullOrWhiteSpace(request.ResponseLengthHex))
                    {
                        int 目标长度值 = Convert.ToInt32(request.ResponseLengthHex, 16);
                        request.ResponseLength = (ushort)目标长度值;
                    }
                }
                //eLog.AddLog("2");
                //发送指令前数据初始化
                if (!数据.初始化(request.Channel, out ZLGCANHelper zLGCANHelper))
                {
                    return new CanReadResponseModel() { Success = false, ErrorMessage = "启动can设备失败" };
                }
                if (request.IsClearCache)
                {
                    _ = zLGCANHelper.RecvData(request.Channel, 0x769, 300, 100);
                    System.Threading.Thread.Sleep(50);
                }
                if (request.IsDecode)
                {
                    var 解密结果 = Can.解密(request.Channel, new List<ZCAN_Receive_Data>(), out string 信息, request.DecodeLevel);
                    if (!解密结果)
                    {
                        return new CanReadResponseModel() { Success = false, ErrorMessage = "解密失败" };
                    }
                }
                //eLog.AddLog("3");
                //发送指令
                var 发送结果 = false;
               
                for (int i = 0; i < request.MaxSendCount; i++)
                {
                    发送结果 = false;
                    for (int j = 0; j < request.CmdList.Count(); j++)
                    {
                       
                        //发送结果 = zLGCANHelper.SentData(request.Channel, 0x761, request.CmdList[j].cmd, true, SendType.正常发送);
                        发送结果 = zLGCANHelper.SentData(request.Channel, request.CmdList[j].Id, request.CmdList[j].cmd, true, SendType.正常发送);
                        System.Threading.Thread.Sleep(request.SendCmdTimeSpan);
                        if (!发送结果)
                        {
                            eLog.AddLog("");
                            break;  //指令发送失败，跳出循环
                        }
                    }
                    if (发送结果 == true)
                    {
                        break;  //指令发送成功，跳出循环
                    }
                }
                if (发送结果 == false)
                {
                    return new CanReadResponseModel() { Success = false, ErrorMessage = "指令发送失败" };
                }
              
                if (request.RequestMode == CanRequestMode.仅发送)
                {
                    return new CanReadResponseModel() { Success = true };  //仅发送模式，发送成功了，直接返回
                }
               
                //接收响应值
                List<ZCAN_Receive_Data> zCAN_Receive_Datas = zLGCANHelper.RecvData(request.Channel, 0x769, 3, request.ReceiveCmdTimeSpan);
                string[] datas = ZLGCanTool.GetData(zCAN_Receive_Datas);
                responseModel.ResultList = datas.ToList();
               
                if (request.AutoParse)
                {
                    if (request.IsVerifyDid)
                    {
                        var 截取请求Did结果 = GetDid(request.CmdList, out string 请求Did);
                        if (!截取请求Did结果)
                        {
                            responseModel.Success = false;
                            responseModel.ErrorMessage = "自动解析响应值失败，截取请求Did失败";
                            return responseModel;
                        }
                        var 校验结果 = CheckDid(responseModel.ResultList, 请求Did);
                        if (!校验结果)
                        {
                            responseModel.Success = false;
                            responseModel.ErrorMessage = "自动解析响应值失败，请求Did与响应Did不匹配";
                            return responseModel;
                        }
                    }

                    int 响应值长度 = GetResponseLength(responseModel.ResultList);
                    if (响应值长度 == -1)
                    {
                        responseModel.Success = false;
                        responseModel.ErrorMessage = "自动解析响应值失败，解析响应值长度失败";
                        return responseModel;
                    }
                    if (响应值长度 != request.ResponseLength)
                    {
                        responseModel.Success = false;
                        responseModel.ErrorMessage = "响应值长度与目标长度不匹配";
                        return responseModel;
                    }
                    var 解析结果 = GetResponContent(responseModel.ResultList, 响应值长度, out string 响应值Hex, out string 响应值Asc);
                    if (!解析结果)
                    {
                        responseModel.Success = false;
                        responseModel.ErrorMessage = "自动解析响应值失败，解析响应值内容失败";
                        return responseModel;
                    }

                    responseModel.ResultHex = 响应值Hex;
                    responseModel.ResultAsc = 响应值Asc;
                }

                responseModel.Success = true;
                return responseModel;
            }
            catch (Exception ex)
            {
                responseModel.Success = false;
                responseModel.ErrorMessage = ex.Message;
                eLog.AddLog($"[ZLGCANoptimize.数据.发送指令]异常，{ex.Message}，{ex.StackTrace}，" +
                    $"发送指令内容：{string.Join(",", request.CmdList.Select(obj => obj.cmd) ?? new List<string>())}", eMsgType.Error);
             
            }
            return responseModel;
        }


        //============================ 辅助方法 ====================================
        /// <summary>
        /// 指令长度检查
        /// </summary>
        /// <param name="cmdList"></param>
        /// <returns></returns>
        private static bool CheckCmdLength(List<CanCmdModel> list)
        {
            var cmdList = list.Select(obj => obj.cmd).ToList();
            foreach (var 单条指令 in cmdList)
            {
                var strArray = 单条指令.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                if (strArray.Length != 8)
                {
                    return false;  //指令长度不匹配
                }
            }
            return true;
        }
        /// <summary>
        /// 获取响应值长度
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        private static int GetResponseLength(List<string> list)
        {
            if (list.Count <= 0)
            {
                return -1;
            }

            var ret = list.Where(obj => obj.TrimStart().StartsWith("10")).First();
            if (null != ret)
            {
                var strArray = ret.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                if (strArray.Length == 8)
                {
                    string hexValue = strArray[1];
                    bool success = int.TryParse(hexValue, System.Globalization.NumberStyles.HexNumber, null, out int decimalValue);
                    if (success)
                    {
                        return decimalValue;  //将十六进制的长度值转换为十进制表示并返回
                    }
                }
            }

            return -1;
        }
        /// <summary>
        /// 获取发送指令中对应的did
        /// </summary>
        /// <param name="list"></param>
        /// <param name="did"></param>
        /// <returns></returns>
        private static bool GetDid(List<CanCmdModel> canCmdList, out string did)
        {
            var list = canCmdList.Select(obj => obj.cmd).ToList();
            did = string.Empty;
            var 无空格did = did.Replace(" ", "").Trim();

            foreach (var v in list)
            {
                var 无空格指令 = v.Replace(" ", "").Trim();
                if (!无空格指令.StartsWith("03"))
                {
                    continue;  //不存在did的指令格式，直接过滤掉
                }

                //03 22 F1 B6 00 00 00 00，其中 F1 B6 为did
                did = 无空格指令.Substring(4, 4);
                return true;
            }

            return false;
        }
        /// <summary>
        /// 校验响应指定中的did与指定did是否匹配
        /// </summary>
        /// <param name="list"></param>
        /// <param name="did"></param>
        /// <returns></returns>
        public static bool CheckDid(List<string> list, string did)
        {
            var 无空格did = did.Replace(" ", "").Trim();

            foreach (var v in list)
            {
                var 无空格指令 = v.Replace(" ", "").Trim();
                if (!无空格指令.StartsWith("03") && !无空格指令.StartsWith("06"))
                {
                    continue;  //不存在did的指令格式，直接过滤掉
                }

                //03 22 F1 B6 00 00 00 00，其中 F1 B6 为did
                if (无空格指令.Substring(4, 4) == 无空格did)
                {
                    return true;
                }
            }

            return false;
        }
        /// <summary>
        /// 获取响应值内容
        /// </summary>
        /// <param name="响应值列表"></param>
        /// <param name="响应值长度"></param>
        /// <param name="响应值Hex"></param>
        /// <param name="响应值Asc"></param>
        /// <returns></returns>
        private static bool GetResponContent(List<string> 响应值列表, int 响应值长度, out string 响应值Hex, out string 响应值Asc)
        {
            
            //可能也会有24、25连续帧数据的内容，也兼容做处理，2024-12-03
            响应值Hex = string.Empty;
            响应值Asc = string.Empty;
            bool ok10 = false, ok21 = true, ok22 = true, ok23 = true, ok24 = true, ok25 = true;
            string[] resultArray = new string[1];
            if (响应值长度 > 6)
            {
                ok21 = false;
                resultArray = new string[2];
            }
            if (响应值长度 > 13)
            {
                ok22 = false;
                resultArray = new string[3];
            }
            if (响应值长度 > 20)
            {
                ok23 = false;
                resultArray = new string[4];
            }
            if (响应值长度 > 27)
            {
                ok24 = false;
                resultArray = new string[5];
            }
            if (响应值长度 > 34)
            {
                ok25 = false;
                resultArray = new string[6];
            }

            foreach (string 单条响应值 in 响应值列表)
            {
                if (单条响应值.Trim().StartsWith("10"))
                {
                    ok10 = true;
                    resultArray[0] = 单条响应值;
                }
                else if (单条响应值.Trim().StartsWith("21"))
                {
                    ok21 = true;
                    resultArray[1] = 单条响应值;
                }
                else if (单条响应值.Trim().StartsWith("22"))
                {
                    ok22 = true;
                    resultArray[2] = 单条响应值;
                }
                else if (单条响应值.Trim().StartsWith("23"))
                {
                    ok23 = true;
                    resultArray[3] = 单条响应值;
                }
                else if (单条响应值.Trim().StartsWith("24"))
                {
                    ok24 = true;
                    resultArray[4] = 单条响应值;
                }
                else if (单条响应值.Trim().StartsWith("25"))
                {
                    ok25 = true;
                    resultArray[5] = 单条响应值;
                }
            }
            if (!ok10 || !ok21 || !ok22 || !ok23 || !ok24 || !ok25)
            {
                return false;  //响应值解析有误
            }

            //根据响应值长度，截取最终结果值
            List<string> resultList = new List<string>();
            for (int i = 0; i < resultArray.Length; i++)
            {
                var strArray = resultArray[i].Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                switch (i)
                {
                    case 0:
                        resultList.Add(string.Join(" ", strArray.Skip(2).Take(7)));
                        break;
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                        resultList.Add(string.Join(" ", strArray.Skip(1).Take(7)));
                        break;
                    default:
                        break;
                }
            }

            //截取目标内容
            resultList = resultList.Take(响应值长度).ToList();
            响应值Hex = string.Join(" ", resultList);
            foreach (var hex in resultList)
            {
                int value = Convert.ToInt32(hex, 16);
                string stringValue = Char.ConvertFromUtf32(value);
                响应值Asc += stringValue;
            }

            return true;
        }
        /// <summary>
        /// 从响应值中提取指定数据帧头数据
        /// </summary>
        /// <param name="list"></param>
        /// <param name="frameHeader"></param>
        /// <returns></returns>
        public static bool GetFrameHeaderData(List<string> list, string frameHeader, out string 目标值)
        {
            目标值 = string.Empty;
            foreach (var v in list)
            {
                if (v.TrimStart().StartsWith(frameHeader))
                {
                    目标值 = v.Trim().Replace(" ", "");  //返回目标值不带空格
                    return true;
                }
            }
            return false;
        }
    }
}
